package com.jspx.txweb.dispatcher.service;

import com.jspx.boot.environment.Environment;
import com.jspx.boot.sign.ErrorRocCode;
import com.jspx.json.JSONException;
import com.jspx.json.JSONObject;
import com.jspx.json.XML;
import com.jspx.txweb.ActionInvocation;
import com.jspx.txweb.config.ActionConfig;
import com.jspx.txweb.dispatcher.Dispatcher;
import com.jspx.txweb.dispatcher.IService;
import com.jspx.txweb.proxy.DefaultActionInvocation;
import com.jspx.txweb.result.WebServiceResult;
import com.jspx.txweb.support.ActionSupport;
import com.jspx.txweb.util.TXWebUtil;
import com.jspx.utils.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;

/**
 * 封装 ActionInvocation 提供外部调用
 */
public class RocService  extends IService {
    final public static String  name = "roc";

    public String doing(HttpServletRequest request, HttpServletResponse response,String call)  throws Exception
    {
        ///////////////////读取ajax请求 end
        if (StringUtil.isNULL(call)) {
            JSONObject errorResultJson = TXWebUtil.createRocErrorInfo(URLUtil.getFileNamePart(request.getRequestURI()), ErrorRocCode.invalidParameters, "Invalid params.参数无效,无效的请求");
            return errorResultJson.toString(4);
        }
        //////////////////初始begin
        if (call.length()>20480)
        {
            JSONObject errorResultJson = TXWebUtil.createRocErrorInfo(URLUtil.getFileNamePart(request.getRequestURI()), ErrorRocCode.invalidParameters, "Invalid params.参数无效,长度超出范围");
            return errorResultJson.toString(4);
        }
        return callAction( request,  response, call,false);
    }

    String callAction(HttpServletRequest request, HttpServletResponse response, String call, boolean secret) throws Exception
    {
        //判断是XML还是JSON begin

        String rpc = StringUtil.trim(call);
        JSONObject jsonData = null;
        boolean jsonFormat = true;
        if (StringUtil.isXml(rpc))
        {
            //XML格式
            try {
                jsonData = XML.toJSONObject(rpc);
            } catch (JSONException e) {
                JSONObject errorResultJson = TXWebUtil.createRocErrorInfo(URLUtil.getFileNamePart(request.getRequestURI()), ErrorRocCode.invalidParameters, "Invalid params.参数无效,无效的请求");
                return "<?xml version=\"1.0\" encoding=\"" + Dispatcher.getEncode() + "\"?>\r\n" + XMLUtil.format(XML.toString(errorResultJson, Environment.rocResult));
            }
            jsonFormat = false;

        } else
        if (StringUtil.isJsonObject(rpc))
        {
            //JSON格式
            try {
                jsonData = new JSONObject(rpc);
            } catch (JSONException e) {
                JSONObject errorResultJson = TXWebUtil.createRocErrorInfo(URLUtil.getFileNamePart(request.getRequestURI()), ErrorRocCode.invalidParameters, "Invalid params.参数无效,无效的请求");
                return errorResultJson.toString(4);
            }
        }

        if (jsonData==null)
        {
            JSONObject errorResultJson = TXWebUtil.createRocErrorInfo(URLUtil.getFileNamePart(request.getRequestURI()), ErrorRocCode.invalidParameters, "Invalid params.参数无效,不能识别的格式");
            return errorResultJson.toString(4);
        }
        //判断是XML还是JSON end


        JSONObject methodCall = jsonData.getJSONObject(Environment.rocMethodCall);
        //兼容格式调整
        if (methodCall!=null) jsonData = methodCall;

        //////////////////初始end

        String namespace = null;
        String namePart = jsonData.getString(Environment.rocId);
        if (StringUtil.isNULL(namePart)) namePart = URLUtil.getFileNamePart(request.getRequestURI());
        if (namePart!=null && namePart.contains(TXWebUtil.AT))
        {
            namespace = StringUtil.substringAfter(namePart,TXWebUtil.AT);
            namePart = StringUtil.substringBefore(namePart,TXWebUtil.AT);
        } else
        {
            namespace = jsonData.getString(Environment.namespace);
        }
        if (namespace==null)
            namespace = TXWebUtil.getNamespace(request.getServletPath());
        ///////////////////////////////////环境参数 begin
        Map<String, Object> envParams = TXWebUtil.createEnvironment();
        envParams.put(ActionSupport.Key_RealPath, Dispatcher.getRealPath());
        envParams.put(ActionSupport.Key_Request, request);
        envParams.put(ActionSupport.Key_Response, response);
        ///////////////////////////////////环境参数 end

        envParams.put(ActionSupport.Key_ActionName, namePart);
        envParams.put(ActionSupport.Key_Namespace, namespace);
        if (StringUtil.isNULL(jsonData.getString("id"))) jsonData.put("id",namePart);
        ActionConfig actionConfig = webConfigManager.getActionConfig(namePart, namespace, true);
        if (actionConfig == null) {
            envParams.clear();
            JSONObject errorResultJson = TXWebUtil.createRocErrorInfo(URLUtil.getFileNamePart(request.getRequestURI()), ErrorRocCode.invalidParameters, "class not found.找不到执行对象");
            return errorResultJson.toString(4);
        }

        if (secret!=actionConfig.isSecret())
        {
            JSONObject errorResultJson = TXWebUtil.createRocErrorInfo(URLUtil.getFileNamePart(request.getRequestURI()), ErrorRocCode.invalidParameters, "forbidden not secret request call.禁止非加密方式调用");
            return errorResultJson.toString(4);
            //加密调用这里返回
        }
        jsonData.put(Environment.rocFormat,jsonFormat?"json":"xml");

        //在高并发下，ajax请求会出现异常，必须使用synchronized

        //执行action返回数据begin
        ActionInvocation actionInvocation = new DefaultActionInvocation(actionConfig,envParams,jsonData, request, response);
        actionInvocation.initAction();
        actionInvocation.invoke();
        WebServiceResult serviceResult = new WebServiceResult();
        actionInvocation.executeResult(serviceResult);
        return serviceResult.getResult();
        //执行action返回数据end
    }
}
